// Whiteboard.java

/*
**  Licensed Materials - Property of IBM
**
**  (C) COPYRIGHT IBM Corp. 1996, 1997  All rights reserved
**
**  US Government Users Restricted Rights - Use, duplication or
**  disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
**
**/

package	com.ibm.tspaces.examples.whiteboard;

import java.awt.event.*;
import java.awt.*;
import java.applet.*;
import java.net.*;
import java.util.Vector;
import java.lang.reflect.*;
import com.ibm.tspaces.*;
/**
** This class implements a 'shared' whiteboard to be used with
** tuplespace. This may not be a great implementation of a 
** whiteboard application, but it does demo how to use TupleSpace
** 
** All of the Tuplespace related code is WhiteboardPanel.java
** 
** @version $Revision: 2.1.2.1 $ $Date: 2000/02/05 14:52:31 $
** @author <a href="mailto:eichstam@almaden.ibm.com">Matthias Eichstaedt</a>
** @author <a href="mailto:jthomas@cruzio.com">John Thomas</a>

*/
public class Whiteboard extends Applet{

	private static Whiteboard whiteboard;
 	public static boolean application = false;
    // WhitespacesPanel will use these if set    
    protected static String host=null;
    protected static int port=-1;
    
    // This will be set true when start() called and 
    // set to false when stop() is called;
    protected static boolean PaintOK = true;
    
    protected static final int WIDTH = 240;
    protected static final int HEIGHT = 300;
    //private WhiteboardPanel wp = null;
    private Panel wp = null;
	public Frame 	appFrame;
	private boolean applet = false;
	
	private boolean Error = false;
	private String ErrorMsg = "";
	
public 
Whiteboard() {
		System.out.println("Constructor entered");
}
    /*
    ***************************************************************************
    ** ** init **
    ** **********
    */
    /**
    ** Initialization: 
    ** This could be entered automatically when running as an applet 
    ** or by being called from main() is being run from an 
    ** application.
    **
    **
    *************************************************************************** 
    */
    public void init() {
    	//System.out.println("init()");
    	if (application) {                 // Running as an application
    	    
    		appFrame = new Frame("T Spaces Whiteboard");
    		appFrame.add("Center", whiteboard);
            appFrame.setSize(WIDTH,HEIGHT);   
    	} else  {    // Running as an applet
    	
    		applet = true;
    		whiteboard = this;  
    		// We will assume that Tuplespace is on same host as applet codebase
    		URL url = getCodeBase();
    		String urlhost = url.getHost();
    		System.out.println("Host="+urlhost);
    		if (urlhost.length() != 0) 
    		    host = urlhost;
    	    String strport  = getParameter("port");
    	    if (strport != null) 
    	    	try { 
    	    		port = Integer.valueOf(strport).intValue();		        
		    	} catch (NumberFormatException nfe) {
		    		ErrorMsg = "Invalid Port specification: " + strport;
		    		System.out.println(ErrorMsg);
		    		this.showStatus(ErrorMsg);		    	
		    		Error = true;
				}
    		System.out.println("Port="+port);
    		
    
    	}
    	
    	whiteboard.setLayout(new BorderLayout());
    	// --------------------------------------------------------------
    	// Now we want to create the instance of WhiteboardPanel
    	// but it has JDK 1.1 eventmodel code that may not be supported 
    	// by the browser.  So we will cause it to be loaded and invoked 
    	// under a try/catch block that will handle any errors.
    	// 
    	// Note that we have had to be careful to remove any reference 
    	// to WhiteboardPanel or WhiteboardControls from this code so that
    	// they will not be loaded earlier.
    	if ( ! Error ) 
	    	try {
	    		Class wpclass = Class.forName("com.ibm.tspaces.examples.whiteboard.WhiteboardPanel");
	        	if ( wpclass != null )
	        		whiteboard.wp = (Panel)wpclass.newInstance();
	        	if ( wpclass == null || whiteboard.wp == null) 
	        		throw new Exception("Whiteboard Creation Error");
	        	// We have the Panel object, so add it to the layout
	        	whiteboard.add("Center", wp);
	            // now we need to call wp.init(this) 
	        	Class myClass[] = { Whiteboard.class };
	        	Method initMethod = wpclass.getMethod("init",myClass);   
	        	Object param[] = { this };
	        	initMethod.invoke(wp, param);
	        } catch (Exception e) {
	        	if (applet) 
	        		if ( e.getMessage().endsWith("Listener"))
	        			ErrorMsg = "Your browser does not fully support JDK 1.1; Class="+e.getMessage();
	        		else
	        			ErrorMsg = "Browser error while loading class: " +	e.getMessage();
	        	else
	        		ErrorMsg = "Exception while loading class WhiteboardPanel: " +	e.getMessage();
 
	        	System.out.println(ErrorMsg);
	        	if (applet) 
	        		this.showStatus(ErrorMsg);
	        	e.printStackTrace();
	        	Error = true;
	        	
	        }  catch (Error err) {
	        
	        	ErrorMsg = 
	        	  "Error while loading class WhiteboardPanel: " +	
	        	  err.getMessage() + "\n" + err.toString();
 
	        	System.out.println(ErrorMsg);
	        	if (applet) 
	        		this.showStatus(ErrorMsg);
	        	err.printStackTrace();
	        	Error = true;
	        	
	        }

        
        if (Error) {
        	Label err = new Label(ErrorMsg);
        	whiteboard.add("South",err);
        }				
        
   
		if ( ! applet) 
			appFrame.show();
		else {
			
    	}	
             

    } // init
	
	/*
    ***************************************************************************
    ** ** run **
    ** **********
    */
    /**
    ** run: Is entered as as a result of a start thread 
    ** It is not currently being used.
    **
    *************************************************************************** 
    */
   

	
	public void
	run() {
		System.out.println("run()");
		while (true) 
			try {
				Thread.currentThread().sleep(5000);
		    } catch (InterruptedException ie) {}
	}
	
	/*
    ***************************************************************************
    ** ** start **
    ** **********
    */
    /**
    ** start() is called when it is time for the applet to start doing stuff.
    **
    ** This could be called multiple times as the applet is stopped and started. 
    **
    **
    *************************************************************************** 
    */
    public void 
    start()  {
		System.out.println("start()");
		PaintOK = true;
	}
	
	/*
    ***************************************************************************
    ** ** stop **
    ** **********
    */
    /**
    ** stop() is called when the applet is no longer visible so we no longer need to 
    ** keep painting the screen, but we should still listen for events.
    **
    ** This could be called multiple times as the applet is stopped and started. 
    **
    **
    *************************************************************************** 
    */
    public void 
    stop()  {
		System.out.println("stop()");
		PaintOK = false;
	}
	
	/*
    ***************************************************************************
    ** ** destroy **
    ** **********
    */
    /**
    ** destroy() is called when the applet is going to be permanently stoped
    **
    **
    *************************************************************************** 
    */
    public void 
    destroy()  {
		System.out.println("destroy()");
		wp.removeAll();   // cause WhiteboardPanel to get control
	}

	
    /*
    ***************************************************************************
    ** ** main **
    ** **********
    */
    /**
    ** Run the whiteboard as an application.
    **
    ** @param args - command line arguments
    *************************************************************************** 
    */
    public static void main(String args[]) {
        application = true;
        whiteboard = new Whiteboard();
        if(args.length >= 1)
        	host = args[0]; 
       	if(args.length >= 2) {
			try {				
				port = Integer.valueOf(args[1]).intValue();
		        
		    } catch (NumberFormatException nfe) {
		    	System.out.println("Invalid Port specification: " + args[1]);
			}
		}

        whiteboard.init();
        
        whiteboard.start();

        
                
           /****
              // If we wanted to start out own server we
              // could do the following
              
              private TSServer tss = null;
    		  private Thread tsServerThread = null;
              
                whiteboard.tss = new TSServer();
                whiteboard.tsServerThread = new Thread(whiteboard.tss);
                whiteboard.tsServerThread.start();
                whiteboard.ts = new TupleSpace("Whiteboard");
            ******/
    } // main
} // Whiteboard

/*
$History: Whiteboard.java $
 * 
 * *****************  Version 2  *****************
 * User: Jthomas      Date: 3/11/98    Time: 7:00p
 * Updated in $/GCS/Development/TSpaces/Java/com/ibm/tspaces/examples/whiteboard
 * Fix Bluespaces in title and make wider
 * 
 * *****************  Version 1  *****************
 * User: Toby         Date: 1/23/98    Time: 9:55a
 * Created in $/GCS/Development/TSpaces/Java/com/ibm/tspaces/examples/whiteboard
 * 
 * *****************  Version 9  *****************
 * User: Jthomas      Date: 12/10/97   Time: 8:24a
 * Updated in $/GCS/Development/bluespaces/Java/com/ibm/bluespaces/examples/whiteboard
 * Handle start/stop/destroy methods
 * Display msg to user on any exception 
 * 
 * *****************  Version 8  *****************
 * User: Jthomas      Date: 11/29/97   Time: 12:26p
 * Updated in $/GCS/Development/bluespaces/Java/com/ibm/bluespaces/examples/whiteboard
 * update comments and add code to catch more error conditions
 * 
 * *****************  Version 7  *****************
 * User: Jthomas      Date: 11/26/97   Time: 4:41p
 * Updated in $/GCS/Development/bluespaces/Java/com/ibm/bluespaces/examples/whiteboard
 * Whiteboard - fix for browsers that don't support JDK 1.1
 * 
 * *****************  Version 6  *****************
 * User: Jthomas      Date: 11/24/97   Time: 10:48a
 * Updated in $/GCS/Development/bluespaces/Java/com/ibm/bluespaces/examples/whiteboard
 * Lots of changes:
 *    Moved all TupleSpace code to WhiteboardPanel
 *    Added Erase feature
 *    Only write new Lines and points to TS
 *    Handle host/port
 *    misc
 * 
 * *****************  Version 5  *****************
 * User: Jthomas      Date: 11/18/97   Time: 10:25a
 * Updated in $/GCS/Development/bluespaces/Java/com/ibm/bluespaces/examples/whiteboard
 * Changes so that it works as an applet and an application
 * 
 * *****************  Version 4  *****************
 * User: Toby         Date: 10/02/97   Time: 6:38p
 * Updated in $/GCS/Development/bluespaces/Java/com/ibm/bluespaces/examples/whiteboard
 * Changed most of these (copypaste thru Rhonda) to the new lower case com
 * model.  Also cleaned up a few deprecated APIs and got some old stuff
 * working (or at least commented out).  Will be back for the remaining
 * examples sometime later.
 * 
 * *****************  Version 2  *****************
 * User: Eichstam     Date: 8/12/97    Time: 6:34p
 * Updated in $/GCS/Development/Java/COM/ibm/almaden/tuplespace/examples/whiteboard
 * added the callback mechanism
 * 
 * *****************  Version 1  *****************
 * User: Eichstam     Date: 7/18/97    Time: 1:22a
 * Created in $/GCS/Development/Java/COM/ibm/almaden/tuplespace/examples/whiteboard
 * initial version of the GCS 'shared' whiteboard
*/
/* $Log: Whiteboard.java,v $
/* Revision 2.1.2.1  2000/02/05 14:52:31  jthomas
/* avoid System exit if applet
/*
/* Revision 2.1  1999/11/05 22:22:40  estesp
/* Update revision number to 2.1 on all files
/*
/* Revision 1.1.1.1  1999/11/05 16:24:53  estesp
/* Imported 2.1.0 release into Austin CVS
/*
 * Revision 1.3  1999/09/26 07:54:34  jthomas
 * Modify so it looks better on the Nino PDA
 *
 * Revision 1.2  1999/06/17 05:39:47  thodes
 *   Updated the inital checkin to append the "Log" field and
 * convert CR/LF to CR (for win/unix interop).
 *
 *   The inital checkin lower-cased directrory names, and omitted
 * many dirs/files that will added later, e.g., MoDAL stuff.
 *
 * All of the above will need to be done to all VSS-to-CVS
 * converted sources.  In summary, in moving from VSS to CVS, do this:
 *  - lower-case dir names
 *  - CR/LF --> CR
 *  - append CVS "Log" entties
 *
 * (a script that helps with #2 and #3 is in
 *     tspaces1:~thodes/bin/update-keywords.sh)
 * 
 */

